/*
 * Copyright (C) 2018 Light Team Software
 *
 * This file is part of ModPE IDE.
 *
 * ModPE IDE is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ModPE IDE is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.github.ahmadaghazadeh.editor.processor.language;

import com.github.ahmadaghazadeh.editor.processor.utils.text.ArrayUtils;

import java.util.regex.Pattern;

public class HtmlLanguage extends Language {


    private static final Pattern SYNTAX_NUMBERS = Pattern.compile("(\\b(\\d*[.]?\\d+)\\b)");
    private static final Pattern SYNTAX_SYMBOLS = Pattern.compile(
            "(!|\\+|-|\\*|=|\\?|\\||:|%|&)");
    private static final Pattern SYNTAX_BRACKETS = Pattern.compile("(\\(|\\)|\\{|\\}|\\[|\\])");
    private static final Pattern SYNTAX_KEYWORDS = Pattern.compile(
            "(?<=\\b)((break)|(continue)|(else)|(for)|(function)|(if)|(in)|(new)" +
                    "|(this)|(var)|(while)|(return)|(case)|(catch)|(of)|(typeof)" +
                    "|(const)|(default)|(do)|(switch)|(try)|(null)|(true)" +
                    "|(false)|(eval)|(let)|)(?=\\b)|(:?<|<\\/)([a-zA-Z0-9:.]+)*(:?>|\\/>)|(:?<|<\\/)([a-zA-Z0-9:.]+)|" +
                    "([^\\r\\n,{}]+)(,(?=[^}]*\\{)|\\s*(?=\\{))"); //Слова без CASE_INSENSITIVE
    private static final Pattern SYNTAX_METHODS = Pattern.compile(
            "(?<=(function) )(\\w+)", Pattern.CASE_INSENSITIVE);
    private static final Pattern SYNTAX_STRINGS = Pattern.compile("\"(.*?)\"|'(.*?)'");
    private static final Pattern SYNTAX_COMMENTS = Pattern.compile("/\\*(?:.|[\\n\\r])*?\\*/|//.*");
    private static final char[] LANGUAGE_BRACKETS = new char[]{'{', '[', '(', '}', ']', ')'}; //do not change

    /**
     * Слова для автопродолжения кода.
     */

    private static final String[] BLOCK_KEYWORDS = new String[]{
            "defineBlock", "defineLiquidBlock", "getAllBlockIds", "getDestroyTime",
            "getFriction", "setShape", "getRenderType", "getTextureCoords", "setColor",
            "setDestroyTime", "setExplosionResistance", "setFriction", "setRedstoneConsumer",
            "setLightLevel", "setLightOpacity", "setRenderLayer", "setRenderType"
    };
    private static final String[] ENTITY_KEYWORDS = new String[]{
            "getAll", "getAnimalAge", "getArmor", "getArmorCustomName", "getArmorDamage",
            "getEntityTypeId", "getExtraData", "getHealth", "getItemEntityCount",
            "getItemEntityData", "getItemEntityId", "getMaxHealth", "getMobSkin", "getNameTag",
            "getPitch()", "getRenderType", "getRider", "getRiding", "getTarget", "getUniqueId",
            "getVelX()", "getVelY()", "getVelZ()", "getYaw()", "isSneaking()", "remove",
            "removeAllEffects", "removeEffect", "rideAnimal", "setArmor", "setArmorCustomName",
            "setCape", "setCollisionSize", "setExtraData", "setFireTicks", "setHealth",
            "setImmobile", "setMaxHealth", "setMobSkin", "setNameTag", "setPosition",
            "setPositionRelative", "setCarriedItem", "setRenderType", "setRot", "setSneaking",
            "setTarget", "setVelX", "setVelY", "setVelZ", "spawnMob", "addEffect"
    };
    private static final String[] ITEM_KEYWORDS = new String[]{
            "getMaxDamage", "getMaxStackSize", "defineArmor", "defineThrowable",
            "getCustomThrowableRenderType", "addCraftRecipe", "setMaxDamage", "addFurnaceRecipe",
            "getName", "getTextureCoords", "getUseAnimation", "internalNameToId", "isValidItem",
            "setCategory", "setEnchantType", "addShapedRecipe", "setHandEquipped", "setProperties",
            "setStackedByData", "setUseAnimation", "translatedNameToId"
    };
    private static final String[] LEVEL_KEYWORDS = new String[]{
            "biomeIdToName", "canSeeSky", "setSpawnerTypeId", "destroyBlock", "explode",
            "getAddress", "getBiome", "getBiomeName", "getBrightness", "getGameMode",
            "getGrassColor", "getDifficulty", "setDifficulty", "getTile", "getData", "getTime",
            "getWorldDir()", "getWorldName", "setGameMode", "setGrassColor", "getLightningLevel()",
            "getRainLevel()", "setNightMode", "setSpawn", "setTile", "setTime", "spawnMob",
            "getSignText", "setSignText", "addParticle", "playSound", "playSoundEnt",
            "setBlockExtraData", "dropItem", "getChestSlot", "getChestSlotCount",
            "getChestSlotData", "setChestSlot", "setChestSlotCustomName", "setSpawnerEntityType",
            "setLightningLevel", "setRainLevel", "getFurnaceSlot", "getFurnaceSlotCount",
            "getFurnaceSlotData", "setFurnaceSlot"
    };
    private static final String[] MODPE_KEYWORDS = new String[]{
            "getOS()", "dumpVtable", "getI18n", "getBytesFromTexturePack", "getLanguage",
            "getMinecraftVersion", "langEdit", /*"leaveGame"*/"openInputStreamFromTexturePack",
            "overrideTexture", "readData", "removeData", "saveData", "resetFov", "resetImages",
            "setFoodItem", "setFov", "setGameSpeed", "setItem", "showTipMessage",
            "setUiRenderDebug", "takeScreenshot", "setGuiBlocks", "setItems", "setTerrain",
            "selectLevel"
    };
    private static final String[] PLAYER_KEYWORDS = new String[]{
            "addExp", "addItemInventory", "addItemCreativeInv", "canFly()", "clearInventorySlot",
            "enchant", "getEnchantments", "getArmorSlot", "getArmorSlotDamage", /*"getCarriedItem"*/
            "getCarriedItemCount", "getCarriedItemData", "getDimension", "getEntity",
            "getExhaustion", "getExp", "getHunger", "getInventorySlot", "getInventorySlotCount",
            "getInventorySlotData", "getItemCustomName", "setInventorySlot", "getLevel", "setLevel",
            "setSaturation", "setSelectedSlotId", "setItemCustomName", "getName",
            "getPointedBlockId()", "getPointedBlockData()", "getPointedBlockSide()",
            "getPointedBlockX()", "getPointedBlockY()", "getPointedBlockZ()", "getPointedEntity()",
            "getPointedVecX()", "getPointedVecY()", "getPointedVecZ()", "getSaturation", "getScore",
            "getSelectedSlotId()", /*"getX", "getY", "getZ",*/ "isFlying()", "setCanFly",
            "setFlying", /*"setHealth"*/"setArmorSlot", "setExhaustion", "setExp",
            /*"addItemCreativeInv",*/ "setHunger", "isPlayer()"
    };
    private static final String[] SERVER_KEYWORDS = new String[]{
            /*"getAddress",*/ "getAllPlayerNames()", "getAllPlayers()", "getPort()", "joinServer",
            "sendChat"
    };
    private static final String[] HOOKS_KEYWORDS = new String[]{
            "useItem", /*"destroyBlock",*/ "newLevel", "procCmd", "selectLevelHook",
            /*"leaveGame",*/ "attackHook", "modTick", "eatHook", "explodeHook", "deathHook",
            "entityAddedHook", "entityRemovedHook", "entityHurtHook", "projectileHitEntityHook",
            "playerAddExpHook", "playerExpLevelChangeHook", "redstoneUpdateHook",
            "startDestroyBlock", "continueDestroyBlock", "blockEventHook", "levelEventHook",
            "serverMessageReceiveHook", "screenChangeHook", "chatReceiveHook", "chatHook"
    };
    private static final String[] JS_KEYWORDS = new String[]{
            "function"
    };
    private static final String[] GLOBAL_KEYWORDS = new String[]{
            "clientMessage", "getPlayerX()", "getPlayerY()", "getPlayerZ()", "getPlayerEnt()"
    };

    private static final String[] HTML_KEYWORDS = new String[]{
            ":active",
            ":after",
            ":before",
            ":first",
            ":first-child",
            ":first-letter",
            ":first-line",
            ":focus",
            ":hover",
            ":lang",
            ":left",
            ":link",
            ":right",
            ":visited",
            "@charset",
            "@font-face",
            "@import",
            "@media",
            "@page",
            "a",
            "abbr",
            "above",
            "absolute",
            "accept",
            "accept-charset",
            "accesskey",
            "action",
            "address",
            "alt",
            "always",
            "aqua",
            "area",
            "armenian",
            "article",
            "aside",
            "async",
            "attr",
            "audio",
            "auto",
            "autocomplete",
            "autofocus",
            "autoplay",
            "avoid",
            "azimuth",
            "b",
            "background",
            "background-attachment",
            "background-color",
            "background-image",
            "background-position",
            "background-repeat",
            "base",
            "baseline",
            "bdi",
            "bdo",
            "behind",
            "below",
            "bgsound",
            "bidi-override",
            "black",
            "blink",
            "block",
            "blockquote",
            "blue",
            "body",
            "bold",
            "bolder",
            "border",
            "border-bottom",
            "border-bottom-color",
            "border-bottom-style",
            "border-bottom-width",
            "border-collapse",
            "border-color",
            "border-left",
            "border-left-color",
            "border-left-style",
            "border-left-width",
            "border-right",
            "border-right-color",
            "border-right-style",
            "border-right-width",
            "border-spacing",
            "border-style",
            "border-top",
            "border-top-color",
            "border-top-style",
            "border-top-width",
            "border-width",
            "both",
            "bottom",
            "br",
            "button",
            "canvas",
            "capitalize",
            "caption",
            "caption-side",
            "cellpadding",
            "cellspacing",
            "center",
            "center-left",
            "center-right",
            "challenge",
            "charset",
            "checked",
            "circle",
            "cite",
            "cjk-ideographic",
            "class",
            "clear",
            "clip",
            "close-quote",
            "code",
            "col",
            "colgroup",
            "collapse",
            "color",
            "cols",
            "colspan",
            "command",
            "compact",
            "condensed",
            "content",
            "contenteditable",
            "contextmenu",
            "continuous",
            "controls",
            "coords",
            "counter-increment",
            "counter-reset",
            "crop",
            "cros",
            "crosshair",
            "cue",
            "cue-after",
            "cue-before",
            "cursor",
            "data",
            "datalist",
            "datetime",
            "dd",
            "decimal",
            "decimal-leading-zero",
            "default",
            "defer",
            "deg",
            "del",
            "details",
            "dfn",
            "dialog",
            "digits",
            "dir",
            "direction",
            "disabled",
            "disc",
            "display",
            "div",
            "dl",
            "draggable",
            "dropzone",
            "dt",
            "e-resize",
            "element",
            "elevation",
            "em",
            "embed",
            "empty-cells",
            "enctype",
            "ex",
            "expanded",
            "extra-condensed",
            "extra-expanded",
            "far-left",
            "far-right",
            "fast",
            "faster",
            "fieldset",
            "figcaption",
            "figure",
            "fixed",
            "float",
            "font",
            "font-family",
            "font-size",
            "font-size-adjust",
            "font-stretch",
            "font-style",
            "font-variant",
            "font-weight",
            "footer",
            "for",
            "form",
            "formaction",
            "formenctype",
            "formmethod",
            "formnovalidate",
            "formtarget",
            "frame",
            "frameset",
            "fuchsia",
            "georgian",
            "grad",
            "gray",
            "green",
            "h1",
            "h2",
            "h3",
            "h4",
            "h5",
            "h6",
            "head",
            "header",
            "headers",
            "hebrew",
            "height",
            "help",
            "hgroup",
            "hidden",
            "hide",
            "high",
            "higher",
            "hiragana",
            "hiragana-iroha",
            "hr",
            "href",
            "hreflang",
            "html",
            "http-equiv",
            "hz",
            "i",
            "icon",
            "id",
            "iframe",
            "img",
            "inherit",
            "inline",
            "inline-table",
            "input",
            "ins",
            "inside",
            "ismap",
            "italic",
            "justify",
            "katakana",
            "katakana-iroha",
            "kbd",
            "keygen",
            "keytype",
            "khz",
            "kind",
            "label",
            "landscape",
            "lang",
            "left",
            "left-side",
            "leftwards",
            "legend",
            "letter-spacing",
            "level",
            "li",
            "lighter",
            "lime",
            "line-height",
            "line-through",
            "link",
            "list",
            "list-item",
            "list-style",
            "list-style-image",
            "list-style-position",
            "list-style-type",
            "loop",
            "loud",
            "low",
            "lower",
            "lower-alpha",
            "lower-greek",
            "lower-latin",
            "lower-roman",
            "lowercase",
            "ltr",
            "manifest",
            "map",
            "margin",
            "margin-bottom",
            "margin-left",
            "margin-right",
            "margin-top",
            "mark",
            "marker",
            "marker-offset",
            "marks",
            "maroon",
            "marquee",
            "max",
            "max-height",
            "max-width",
            "maxlength",
            "media",
            "medium",
            "menu",
            "menuitem",
            "message-box",
            "meta",
            "meter",
            "method",
            "middle",
            "min",
            "min-height",
            "min-width",
            "mix",
            "move",
            "ms",
            "multicol",
            "multiple",
            "muted",
            "n-resize",
            "name",
            "narrower",
            "nav",
            "navy",
            "ne-resize",
            "no-close-quote",
            "no-open-quote",
            "no-repeat",
            "nobr",
            "noframes",
            "none",
            "normal",
            "noscript",
            "novalidate",
            "nowrap",
            "nw-resize",
            "object",
            "oblique",
            "ol",
            "olive",
            "onabort",
            "onautocomplete",
            "onautocompleteerror",
            "onbeforeprint",
            "onbeforeunload",
            "onblur",
            "oncancel",
            "oncanplay",
            "oncanplaythrough",
            "once",
            "onchange",
            "onclick",
            "onclose",
            "oncontextmenu",
            "oncuechange",
            "ondblclick",
            "ondrag",
            "ondragend",
            "ondragenter",
            "ondragexit",
            "ondragleave",
            "ondragover",
            "ondragstart",
            "ondrop",
            "ondurationchange",
            "onemptied",
            "onended",
            "onerror",
            "onfocus",
            "onhashchange",
            "oninput",
            "oninvalid",
            "onkeydown",
            "onkeypress",
            "onkeyup",
            "onload",
            "onloadeddata",
            "onloadedmetadata",
            "onloadstart",
            "onmessage",
            "onmousedown",
            "onmouseenter",
            "onmouseleave",
            "onmousemove",
            "onmouseout",
            "onmouseover",
            "onmouseup",
            "onmousewheel",
            "onoffline",
            "ononline",
            "onpagehide",
            "onpageshow",
            "onpause",
            "onplay",
            "onplaying",
            "onpointercancel",
            "onpointerdown",
            "onpointerenter",
            "onpointerleave",
            "onpointerlockchange",
            "onpointerlockerror",
            "onpointermove",
            "onpointerout",
            "onpointerover",
            "onpointerup",
            "onpopstate",
            "onprogress",
            "onratechange",
            "onreadystatechange",
            "onredo",
            "onreset",
            "onresize",
            "onscroll",
            "onseeked",
            "onseeking",
            "onselect",
            "onshow",
            "onsort",
            "onstalled",
            "onstorage",
            "onsubmit",
            "onsuspend",
            "ontimeupdate",
            "ontoggle",
            "onundo",
            "onunload",
            "onvolumechange",
            "onwaiting",
            "open",
            "open-quote",
            "optgroup",
            "optimum",
            "option",
            "orphans",
            "outline",
            "outline-color",
            "outline-style",
            "outline-width",
            "output",
            "outside",
            "overflow",
            "overline",
            "p",
            "padding",
            "padding-bottom",
            "padding-left",
            "padding-right",
            "padding-top",
            "page",
            "page-break-after",
            "page-break-before",
            "page-break-inside",
            "param",
            "pattern",
            "pause",
            "pause-after",
            "pause-before",
            "picture",
            "pitch",
            "pitch-range",
            "placeholder",
            "play-during",
            "pointer",
            "portrait",
            "position",
            "poster",
            "pre",
            "preload",
            "progress",
            "pt",
            "pubdate",
            "purple",
            "px",
            "q",
            "quotes",
            "rad",
            "radiogroup",
            "readonly",
            "red",
            "rel",
            "relative",
            "repeat",
            "repeat-x",
            "repeat-y",
            "required",
            "reversed",
            "richness",
            "right",
            "right-side",
            "rightwards",
            "rows",
            "rowspan",
            "rp",
            "rt",
            "rtc",
            "rtl",
            "ruby",
            "run-in",
            "s",
            "s-resize",
            "samp",
            "sandbox",
            "scope",
            "scoped",
            "script",
            "scroll",
            "se-resize",
            "seamless",
            "section",
            "select",
            "selected",
            "semi-condensed",
            "semi-expanded",
            "separate",
            "shadow",
            "shape",
            "show",
            "silent",
            "silver",
            "size",
            "sizes",
            "slow",
            "slower",
            "small",
            "small-caps",
            "small-caption",
            "soft",
            "source",
            "span",
            "speak",
            "speak-header",
            "speak-numeral",
            "speak-ponctuation",
            "speech-rate",
            "spell-out",
            "spellcheck",
            "square",
            "src",
            "srcdoc",
            "srclang",
            "start",
            "static",
            "status-bar",
            "step",
            "stress",
            "strike",
            "strong",
            "style",
            "sub",
            "summary",
            "sup",
            "super",
            "svg",
            "svg:svg",
            "sw-resize",
            "tabindex",
            "table",
            "table-caption",
            "table-cell",
            "table-column",
            "table-column-group",
            "table-footer-group",
            "table-header-group",
            "table-layout",
            "table-row",
            "table-row-group",
            "target",
            "tbody",
            "td",
            "teal",
            "template",
            "text",
            "text-align",
            "text-bottom",
            "text-decoration",
            "text-indent",
            "text-shadow",
            "text-top",
            "text-transform",
            "textarea",
            "tfoot",
            "th",
            "thead",
            "time",
            "title",
            "titleonafterprint",
            "top",
            "tr",
            "track",
            "transparent",
            "type",
            "u",
            "ul",
            "ultra-condensed",
            "ultra-expanded",
            "underline",
            "unicode-bidi",
            "upper-alpha",
            "upper-latin",
            "upper-roman",
            "uppercase",
            "usemap",
            "value",
            "var",
            "vertical-align",
            "video",
            "visibility",
            "visible",
            "voice-family",
            "volume",
            "w-resize",
            "wait",
            "wbr",
            "white",
            "white-space",
            "wider",
            "widows",
            "width",
            "word-spacing",
            "wrap",
            "x-fast",
            "x-high",
            "x-loud",
            "x-low",
            "x-slow",
            "x-soft",
            "xml:base",
            "xml:lang",
            "xmlns",
            "yellow",
            "z-index",
    };

    /**
     * Соединение всех массивов в один. Этот массив и будет использоваться для
     * получения слов в редакторе.
     */
    private static final String[] ALL_KEYWORDS = ArrayUtils.join(String.class,
            BLOCK_KEYWORDS, ENTITY_KEYWORDS, ITEM_KEYWORDS, LEVEL_KEYWORDS, GLOBAL_KEYWORDS,
            MODPE_KEYWORDS, PLAYER_KEYWORDS, SERVER_KEYWORDS, HOOKS_KEYWORDS, JS_KEYWORDS,HTML_KEYWORDS);

    public final Pattern getSyntaxNumbers() {
        return SYNTAX_NUMBERS;
    }

    public final Pattern getSyntaxSymbols() {
        return SYNTAX_SYMBOLS;
    }

    public final Pattern getSyntaxBrackets() {
        return SYNTAX_BRACKETS;
    }

    public final Pattern getSyntaxKeywords() {
        return SYNTAX_KEYWORDS;
    }

    public final Pattern getSyntaxMethods() {
        return SYNTAX_METHODS;
    }

    public final Pattern getSyntaxStrings() {
        return SYNTAX_STRINGS;
    }

    public final Pattern getSyntaxComments() {
        return SYNTAX_COMMENTS;
    }

    public final char[] getLanguageBrackets() {
        return LANGUAGE_BRACKETS;
    }

    public final String[] getAllCompletions() {
        return ALL_KEYWORDS;
    }

}
